/***************************************************************************
 *   Copyright (C) 2011 by The rPem3d developers                           *
 *   elseifkk@users.sf.net                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "analogmeter.h"
#include <qtimer.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qdatetime.h>

void AnalogMeter::mousePressEvent(QMouseEvent *e) {
    switch (e->button()) {
    case LeftButton:
        scaleMeasure(1);
        break;
    case RightButton:
        scaleMeasure(-1);
        break;
    case MidButton:
        maxval=0.;
        currentAngle=measure_begin;
        vold=0.;
        break;
    default:
        e->ignore();
        return;
    }
    e->accept();
    vold=0.;
    update();
}
double AnalogMeter::vtod(double v) {
    if (v<=vmin) {
        return measure_begin;
    } else if (v>=vmax) {
        return measure_len+measure_begin;
    } else {
        return (v-vmin)/(vmax-vmin)*measure_len+measure_begin;
    }
}
void AnalogMeter::setMeasureGeom() {
    num_tick_short=(num_tick_div+1)*num_tick;
    tick_deg            =(double)measure_len/(double)num_tick;
    tick_deg_short=(double)tick_deg/(double)(num_tick_div+1);
    vmax=num_tick*tick_step;
    vmin=0.;
}
void AnalogMeter::scaleMeasure(int f) {
    if (f>0) {
        if (vmax>=100.) return;//<<<<<<<<<<<<<<<<<<<<<<<
        tick_step*=2.;
    } else if (f<0) {
        if (vmax<=1.) return; //<<<<<<<<<<<<<<<<<<<<<<<<<
        tick_step/=2.;
        if (tick_step<=0) tick_step=1.0;
    }
    setMeasureGeom();
    drawBg();
}

void AnalogMeter::drawBg() {
    QPainter p;//(pm);
    pm->fill("black");

    p.begin(pm,this);

    drawBorder(&p);

    p.setWindow(wRect);

    QRect v = p.viewport();
    int d = QMIN( v.width(), v.height() );
    p.setViewport( v.left() + (v.width()-d)/2,
                   v.top() + (v.height()-d)/2, d, d );
    drawMeasure(&p);
    drawLabel(&p);
    drawTitle(&p);

    p.end();
    bitBlt(this,0,0,pm);
}

void AnalogMeter::initAnalogMeter(QString u, QString c, int ticks, double step, int div) {
    if (pm==NULL) pm = new QPixmap(this->size());
    if (!u.isEmpty()) unit=u;
    if (!c.isEmpty()) caption=c;
    num_tick=ticks;
    num_tick_div=div;
    tick_step=step;
    vold=0.;
    maxval=0.;
    currentAngle=measure_begin;
    lastAngle=currentAngle;
    drawBg();
    update();
}

AnalogMeter::AnalogMeter( QWidget *parent, const char *name)
: QWidget( parent, name ) {
    num_tick=num_tick_def;
    num_tick_div=num_tick_div_def;
    tick_step=tick_step_def;
    setMeasureGeom();
    maxval=0.;
    currentAngle=measure_begin;
    vold=0.;
    pm=NULL;
}

void AnalogMeter::updateMeter(double v) {
    if (v==vold) return;
    vold=v;
    if (maxval<v) maxval=v;
    currentAngle=vtod(v);
    update();
}

void AnalogMeter::paintEvent( QPaintEvent *p) {
    bitBlt(this,0,0,pm);
    QPainter paint( this );
    drawMeter( &paint );
}

void AnalogMeter::drawMeasure(QPainter *p) {
    p->save();
    p->setPen(measure_col);
    p->drawArc(frame_x,frame_y,frame_width,frame_height,measure_start_trans,measure_len_trans);
    p->rotate(measure_begin);
    for ( int i=0; i<=num_tick; i++ ) {
        p->drawLine(-frame_x-long_tick ,0, -frame_x,0 );
        p->rotate( tick_deg );
    }

    p->rotate(-tick_deg);

    for (int i=0; i<=num_tick_short; i++) {
        p->drawLine(-frame_x-short_tick, 0, -frame_x, 0);
        p->rotate(-tick_deg_short);
    }
    p->restore();
}
void AnalogMeter::drawBorder(QPainter *p) {
    QPen pen(QPen::SolidLine);
    QRect r=rect();
    p->save();
    p->setBrush(QBrush::NoBrush);

    pen.setColor(border_col2);
    p->setPen(pen);
    p->drawRoundRect(r,10,10);

    pen.setColor(border_col1);
    p->setPen(pen);
    r.setHeight(r.height()-2);
    r.setWidth(r.width()-2);
    r.moveLeft(1);
    r.moveTop(1);
    p->drawRoundRect(r,10,10);

    p->restore();
}

void AnalogMeter::drawArrow(QPainter *p) {
    QPointArray pts;

    p->save();
    p->setPen(arrow_col_out);
    p->setBrush(arrow_col_in);

    p->rotate(currentAngle);

    pts.setPoints( 4, -arrow_width,0, 0,-arrow_width, -frame_x-long_tick,0, 0,arrow_width );
    p->drawConvexPolygon( pts );
    p->restore();
}

void AnalogMeter::drawTitle(QPainter *p) {

    int ix,iy;
    QFont f("Sans Serif");
    f.setBold(true);

    f.setPixelSize(unit_font_size);
    p->setFont(f);
    p->setPen(unit_col);
    ix=-(double)(unit_font_size*unit.length())*0.3;
    iy=unit_offset-unit_font_size*0.2;
    p->drawText(ix,iy,unit);

    f.setPixelSize(caption_font_size);
    p->setFont(f);
    p->setPen(caption_col);
    ix=-(double)(caption_font_size*caption.length())*0.3;
    iy=frame_height/2-caption_font_size*0.2;
    p->drawText(ix,iy,caption);

}
void AnalogMeter::drawMaxVal(QPainter *p) {
    double v;
    int ix,iy;
    QFont f("Sans Serif");
    f.setBold(true);
    QString str;
    QString ss;
    ss=str.sprintf("%4.1f",maxval).stripWhiteSpace();
    f.setPixelSize(maxval_font_size);
    p->setFont(f);
    p->setPen(maxval_col);
    ix=-(double)(maxval_font_size*ss.length())*0.3;
    iy=-frame_height/6+maxval_font_size*0.5;
    p->drawText(ix,iy,ss);
}

void AnalogMeter::drawLabel(QPainter *p) {
    QString str;
    double v;
    int ix,iy;
    QFont f("Sans Serif");
    f.setBold(true);

    f.setPixelSize(label_font_size);
    p->setFont(f);
    p->setPen(label_col);
    double c,s,t;
    double d;
    double r=frame_width/2.-long_tick-label_font_size*1.2;
    for ( int i=0; i<=num_tick; i++ ) {
        t=DEG2RAD(i*tick_deg+measure_start);
        c=cos(t);
        s=sin(t);
        ix=floor(0.5+-c*r-label_font_size*0.6);
        iy=floor(0.5+-s*r+label_font_size*0.5);
        d=i*tick_step;
        if (d<10.&&d!=0.) {
            str.sprintf("%4.1f",d);//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        } else {
            str.sprintf("%4.0f",d);
        }
        p->drawText(ix,iy,str.stripWhiteSpace());
    }
}

void AnalogMeter::drawMeter( QPainter *paint ) {

    paint->save();

    paint->setWindow(wRect);

    QRect v = paint->viewport();
    int d = QMIN( v.width(), v.height() );
    paint->setViewport( v.left() + (v.width()-d)/2,
                        v.top() + (v.height()-d)/2, d, d );

    drawLabel(paint);

    drawMaxVal(paint);
    drawArrow(paint);

    paint->restore();
}

void AnalogMeter::resetMax() {
    maxval=0;
}
